unit uFrmProduto;

interface

uses
  Generics.Collections,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, ImgList, acAlphaImageList, ComCtrls, sListView, StdCtrls,
  ExtCtrls, ToolWin, uProduto, uConstantesSistema, uPesquisa, uMensagemConstante, uMensagensSistema;

type
  TfrmProduto = class(TForm)
    ToolBar: TToolBar;
    tbCriar: TToolButton;
    tbEditar: TToolButton;
    tbExcluir: TToolButton;
    tbSeparator: TToolButton;
    edPesquisar: TButtonedEdit;
    tbSair: TToolButton;
    sListView: TsListView;
    sAlphaImageList: TsAlphaImageList;
    PopupMenu: TPopupMenu;
    mCampos: TMenuItem;
    mID: TMenuItem;
    mNome: TMenuItem;
    N1: TMenuItem;
    mTodos: TMenuItem;
    mFormaPesquisa: TMenuItem;
    mIgual: TMenuItem;
    mContendo: TMenuItem;
    procedure tbCriarClick(Sender: TObject);
    procedure tbSairClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure tbEditarClick(Sender: TObject);
    procedure tbExcluirClick(Sender: TObject);
    procedure edPesquisarChange(Sender: TObject);
    procedure mIDClick(Sender: TObject);
    procedure mIgualClick(Sender: TObject);
    procedure sListViewAdvancedCustomDrawItem(Sender: TCustomListView;
      Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
      var DefaultDraw: Boolean);
    procedure sListViewAdvancedCustomDrawSubItem(Sender: TCustomListView;
      Item: TListItem; SubItem: Integer; State: TCustomDrawState;
      Stage: TCustomDrawStage; var DefaultDraw: Boolean);
    procedure sListViewColumnClick(Sender: TObject; Column: TListColumn);
    procedure sListViewCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    procedure sListViewDblClick(Sender: TObject);
  private
    { Private declarations }
    fProduto : TProduto;
    flista   : Tlist<TProduto>;
    Coluna   : tpColuna;

    function getProduto: TProduto;
    function getLista: TList<TProduto>;

    procedure setProduto(const Value: TProduto);
    procedure setLista(const Value: TList<TProduto>);
  public
    { Public declarations }
    function validaSelecionado(): boolean;
    function ProdutoSelecionado(): TProduto;
    function retornaObjetoPesquisa: TPesquisa;

    procedure preencheLista();
    procedure preencheListView();
    procedure mudarPesquisaSelecionada(const aTag: integer; const aMenuItem: TMenuItem);

    property Produto   : TProduto         read getProduto    write setProduto;
    property lista     : TList<TProduto>  read getLista      write setLista;
  end;

var
  frmProduto: TfrmProduto;

implementation

uses uFrmCriarProduto, uDmUniSQLProduto;

{$R *.dfm}

function TfrmProduto.ProdutoSelecionado: TProduto;
var
  indice : integer;
begin
   for indice := 0 to Lista.Count - 1 do
    begin
       if (Lista.Items[indice].idProduto = StrToInt(sListView.Items[sListView.ItemFocused.Index].Caption)) then
        begin
           result := Lista.Items[indice];
           break;
        end;
    end;
end;

procedure TfrmProduto.edPesquisarChange(Sender: TObject);
begin
   preencheLista();
   preencheListView();
end;

procedure TfrmProduto.FormCreate(Sender: TObject);
begin
   Produto := TProduto.Create;
   lista           := TList<TProduto>.Create;
end;

procedure TfrmProduto.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
   if (Key = VK_ESCAPE) then
    Self.Close;
end;

procedure TfrmProduto.FormShow(Sender: TObject);
begin
   coluna.coluna := campoIDindex;
   coluna.isAsc  := True;

   preencheLista();
   preencheListView();
end;

function TfrmProduto.getLista: TList<TProduto>;
begin
  Result := flista;
end;

function TfrmProduto.getProduto: TProduto;
begin
   Result := fProduto;
end;

procedure TfrmProduto.mIDClick(Sender: TObject);
begin
   mudarPesquisaSelecionada(TMenuItem(Sender).Tag,mCampos);
end;

procedure TfrmProduto.mIgualClick(Sender: TObject);
begin
   mudarPesquisaSelecionada(TMenuItem(Sender).Tag,mFormaPesquisa);
end;

procedure TfrmProduto.mudarPesquisaSelecionada(const aTag: integer;
  const aMenuItem: TMenuItem);
var
  indice : integer;
begin
   // desmarca todos.
   for indice := 0 to aMenuItem.Count - 1 do
    aMenuItem.Items[indice].Checked := False;

   // Marca o selecinado
   for indice := 0 to aMenuItem.Count - 1 do
    begin
       if (aMenuItem.Items[indice].Tag = aTag) then
        begin
           aMenuItem.Items[indice].Checked := True;
           break;
        end;
    end;
end;

procedure TfrmProduto.preencheLista;
begin
   if (trim(edPesquisar.Text) <> '') then
    Lista := dmUniSQLProduto.listarProduto(edPesquisar.Text,retornaObjetoPesquisa())
   else
    Lista := dmUniSQLProduto.listarProduto();
end;

procedure TfrmProduto.preencheListView;
var
  indice   : integer;
  ListItem : TListItem;
begin
   sListView.Items.Clear;
   for indice := 0 to Lista.Count - 1 do
    begin
       ListItem         := sListView.Items.Add;
       ListItem.Caption := IntToStr(Lista.Items[indice].idProduto);
       ListItem.SubItems.Add(Lista.Items[indice].descricao);
       ListItem.SubItems.Add(Lista.Items[indice].codGrupoProduto.nome);
    end;
end;

function TfrmProduto.retornaObjetoPesquisa: TPesquisa;
var
  indice    : integer;
begin
   result := TPesquisa.Create;

   for indice := 0 to mCampos.Count - 1 do
    begin
        if (StringReplace(mCampos.Items[indice].Caption,'&','',[rfReplaceAll]) = 'Todos') and (mCampos.Items[indice].Checked) then
         result.campos := 'idproduto;descricao'
        else if (mCampos.Items[indice].Checked) then
         begin
            if ( mCampos.Items[indice].Caption = 'id'  ) or
               ( mCampos.Items[indice].Caption = '&id' ) then
               result.campos := '&idproduto'
            else
              result.campos := mCampos.Items[indice].Caption;
            break;
         end;
    end;

   for indice := 0 to mFormaPesquisa.Count - 1 do
    begin
       if (mFormaPesquisa.Items[indice].Checked) then
        begin
           result.tipoPesquisa := tpPesquisa(mFormaPesquisa.Items[indice].Tag);
           break;
        end;
    end;

   result.campos := StringReplace(result.campos,'&','',[rfReplaceAll]);
end;

procedure TfrmProduto.setLista(const Value: TList<TProduto>);
begin
  flista := Value;
end;

procedure TfrmProduto.setProduto(const Value: TProduto);
begin
  fProduto := Value;
end;

procedure TfrmProduto.sListViewAdvancedCustomDrawItem(
  Sender: TCustomListView; Item: TListItem; State: TCustomDrawState;
  Stage: TCustomDrawStage; var DefaultDraw: Boolean);
begin
   if Odd(item.index) then
     sListView.Canvas.Brush.Color := clWhite
   else
     sListView.Canvas.Brush.Color := clCream;
end;

procedure TfrmProduto.sListViewAdvancedCustomDrawSubItem(
  Sender: TCustomListView; Item: TListItem; SubItem: Integer;
  State: TCustomDrawState; Stage: TCustomDrawStage; var DefaultDraw: Boolean);
begin
   if Odd(item.index) then
     sListView.Canvas.Brush.Color := clWhite
   else
     sListView.Canvas.Brush.Color := clCream;
end;

procedure TfrmProduto.sListViewColumnClick(Sender: TObject;
  Column: TListColumn);
begin
   if (coluna.coluna = Column.Index) then
    begin
       coluna.isAsc := not (coluna.isAsc);
       sListView.AlphaSort;
    end
   else
    begin
       coluna.isAsc  := True;
       coluna.coluna := Column.Index;
       sListView.AlphaSort;
    end;
end;

procedure TfrmProduto.sListViewCompare(Sender: TObject; Item1,
  Item2: TListItem; Data: Integer; var Compare: Integer);
begin
   if (coluna.coluna = campoIDindex) then
    begin
       if coluna.isAsc then
        Compare:= CompareText(Item1.Caption,Item2.Caption)
       else
        Compare:= CompareText(Item2.Caption, Item1.Caption);
    end
   else
     begin
        if coluna.isAsc then
         Compare:= CompareText(Item1.SubItems[coluna.coluna-1],Item2.SubItems[coluna.coluna-1])
        else
         Compare:= CompareText(Item2.SubItems[coluna.coluna-1],Item1.SubItems[coluna.coluna-1]);
     end;
end;

procedure TfrmProduto.sListViewDblClick(Sender: TObject);
begin
   tbEditarClick(nil);
end;

procedure TfrmProduto.tbCriarClick(Sender: TObject);
begin
   try
      Application.CreateForm(TfrmCriarProduto,frmCriarProduto);

      frmCriarProduto.ShowModal;
      frmCriarProduto.Modo := tpInserir;

      preencheLista();
      preencheListView();
   finally
      if assigned(frmCriarProduto) then
       FreeAndNil(frmCriarProduto);
   end;
end;

procedure TfrmProduto.tbEditarClick(Sender: TObject);
begin
 try
     if validaSelecionado() then
      begin
         Application.CreateForm(TfrmCriarProduto,frmCriarProduto);
         frmCriarProduto.modo      := tpEditar;
         frmCriarProduto.Produto   := ProdutoSelecionado();
         frmCriarProduto.ShowModal;

         preencheLista();
         preencheListView();
      end
     else
      MensagemAviso(MsgErroSelecionado);
   finally
     if assigned(frmCriarProduto) then
      FreeAndNil(frmCriarProduto);
   end;
end;

procedure TfrmProduto.tbExcluirClick(Sender: TObject);
begin
   if not validaSelecionado() then
    MensagemAviso(MsgErroSelecionado)
   else if not (MensagemPergunta(MsgConfimarExclusao) = ID_YES) then
    exit
   else
    begin
       dmUniSQLProduto.excluirProduto(ProdutoSelecionado());

       preencheLista();
       preencheListView();
    end;
end;

procedure TfrmProduto.tbSairClick(Sender: TObject);
begin
  Self.Close;
end;

function TfrmProduto.validaSelecionado: boolean;
begin
   result := (sListView.Items.Count > 0) and (sListView.SelCount > 0);
end;

end.
